package com.uuah.server.exception;

import com.uuah.server.api.IUuahMessage;
import com.uuah.server.api.endpoint.IUuahEndpoint;
import com.uuah.server.message.ExceptionPayload;
import com.uuah.server.message.UuahMessage;
import com.uuah.server.transport.NullPayload;
import com.uuah.server.transport.RequestContextHelper;
import com.uuah.utils.ObjectUtils;

public class ExceptionStrategy extends AbstractExceptionListener {

	public void handleMessagingException(IUuahMessage message, Throwable t) {
		defaultHandler(t);
		routeException(messageFromContextIfAvailable(message), null, t);
	}

	public void handleRoutingException(IUuahMessage message,
			IUuahEndpoint endpoint, Throwable t) {
		defaultHandler(t);
		routeException(messageFromContextIfAvailable(message), endpoint, t);
	}

	public void handleLifecycleException(Object component, Throwable t) {
		handleStandardException(t);
		logger.error("The object that failed was: \n"
				+ ObjectUtils.toString(component, "null"));
	}

	public void handleStandardException(Throwable t) {
		if (RequestContextHelper.getEventContext() != null) {
			handleMessagingException(RequestContextHelper.getEventContext()
					.getMessage(), t);
		} else {
			logger
					.info("There is no current event available, routing Null message with the exception");
			handleMessagingException(new UuahMessage(NullPayload.getInstance()),
					t);
		}
	}

	protected void defaultHandler(Throwable t) {
		if (RequestContextHelper.getEvent() != null) {
			RequestContextHelper.setExceptionPayload(new ExceptionPayload(t));
		}
	}

	protected IUuahMessage messageFromContextIfAvailable(IUuahMessage message) {
		if (null != RequestContextHelper.getEvent()) {
			return RequestContextHelper.getEvent().getMessage();
		} else {
			return message;
		}
	}

}
